AVR675 Configurable Three Phase Fan  2.0
main.c File Reference

 BLDC Sensorless Control using the ATtiny461A for Fan control.
More...

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

Go to the source code of this file.

Defines

#define ADC_MUX_I   0x22
#define ADC_MUX_U   0x25
#define ADC_MUX_V   0x26
#define ADC_MUX_W   0x24
#define ADC_PRESCALER   4
#define bemf   variable_table[8]
#define bemf_error   variable_table[9]
#define CMD_PIN   PA4
#define CMD_PIN_0   (1<<CMD_PIN)
#define CMD_PIN_1   0
#define CMD_PIN_TEST   (PINA & (1<<CMD_PIN))
#define command   variable_table[0]
#define command_0   variable_table[24 + VARIABLE_TABLE_SIZE]
#define command_1   variable_table[26 + VARIABLE_TABLE_SIZE]
#define command_2   variable_table[28 + VARIABLE_TABLE_SIZE]
#define command_3   variable_table[30 + VARIABLE_TABLE_SIZE]
#define counter   variable_table[15]
#define current   variable_table[5]
#define current_limit   variable_table[4]
#define current_limit_max   variable_table[21 + VARIABLE_TABLE_SIZE]
#define current_limit_slope   variable_table[22 + VARIABLE_TABLE_SIZE]
#define current_limit_startup   variable_table[20 + VARIABLE_TABLE_SIZE]
#define data_rxd   variable_table[14]
#define data_watch   variable_table[2 + VARIABLE_TABLE_SIZE]
#define EDGE_FALLING   1
#define EDGE_RISING   0
#define EEPROM_TABLE_SIZE   32
#define enable_voltage   variable_table[0 + VARIABLE_TABLE_SIZE]
#define HALF_LIMIT   0x7FFFu
#define HEADER_SIZE   64
#define input_cmd   variable_table[4 + VARIABLE_TABLE_SIZE]
#define ki   variable_table[9 + VARIABLE_TABLE_SIZE]
#define kp   variable_table[8 + VARIABLE_TABLE_SIZE]
#define LED_PIN   PB6
#define LED_PIN_0   PORTB &= ~(1<<LED_PIN)
#define LED_PIN_1   PORTB |= (1<<LED_PIN)
#define LED_PIN_TOGGLE   PORTB ^= (1<<LED_PIN)
#define LOOP_SCALING   3u
#define LOWER_DRIVE_STEP1_CW   (1 << WL)
#define LOWER_DRIVE_STEP2_CW   (1 << WL)
#define LOWER_DRIVE_STEP3_CW   (1 << VL)
#define LOWER_DRIVE_STEP4_CW   (1 << VL)
#define LOWER_DRIVE_STEP5_CW   (1 << UL)
#define LOWER_DRIVE_STEP6_CW   (1 << UL)
#define mode   variable_table[3 + VARIABLE_TABLE_SIZE]
#define osc_cal   variable_table[12]
#define osc_cal_adj   variable_table[1 + VARIABLE_TABLE_SIZE]
#define osc_error   variable_table[13]
#define pll_gravity   variable_table[10 + VARIABLE_TABLE_SIZE]
#define pwm   variable_table[7]
#define pwm_limit   variable_table[6]
#define pwm_max   variable_table[12 + VARIABLE_TABLE_SIZE]
#define pwm_min   variable_table[11 + VARIABLE_TABLE_SIZE]
#define r0_limit   variable_table[7 + VARIABLE_TABLE_SIZE]
#define s_ki   variable_table[16 + VARIABLE_TABLE_SIZE]
#define s_kp   variable_table[15 + VARIABLE_TABLE_SIZE]
#define s_loop_rate   variable_table[13 + VARIABLE_TABLE_SIZE]
#define s_r0_limit   variable_table[14 + VARIABLE_TABLE_SIZE]
#define speed   variable_table[2]
#define speed_cmd   variable_table[1]
#define speed_cmd_0   variable_table[25 + VARIABLE_TABLE_SIZE]
#define speed_cmd_1   variable_table[27 + VARIABLE_TABLE_SIZE]
#define speed_cmd_2   variable_table[29 + VARIABLE_TABLE_SIZE]
#define speed_cmd_3   variable_table[31 + VARIABLE_TABLE_SIZE]
#define speed_cmd_max   variable_table[18 + VARIABLE_TABLE_SIZE]
#define speed_cmd_min   variable_table[17 + VARIABLE_TABLE_SIZE]
#define speed_count_max   variable_table[6 + VARIABLE_TABLE_SIZE]
#define speed_count_min   variable_table[5 + VARIABLE_TABLE_SIZE]
#define speed_error   variable_table[3]
#define speed_scale   variable_table[19 + VARIABLE_TABLE_SIZE]
#define TACH_PIN   PA0
#define TACH_PIN_0   PORTA |= (1<<TACH_PIN)
#define TACH_PIN_1   PORTA &= ~(1<<TACH_PIN)
#define TEST_PIN   PA3
#define TEST_PIN_0   PORTA &= ~(1<<TEST_PIN)
#define TEST_PIN_1   PORTA |= (1<<TEST_PIN)
#define UH   PB1
#define UL   PB0
#define UPPER_DRIVE_MASK   ((1 << UH) | (1 << VH) | (1 << WH))
#define UPPER_DRIVE_STEP1_CW   (1 << VH)
#define UPPER_DRIVE_STEP2_CW   (1 << UH)
#define UPPER_DRIVE_STEP3_CW   (1 << UH)
#define UPPER_DRIVE_STEP4_CW   (1 << WH)
#define UPPER_DRIVE_STEP5_CW   (1 << WH)
#define UPPER_DRIVE_STEP6_CW   (1 << VH)
#define v_bus   variable_table[10]
#define v_bus_min   variable_table[23 + VARIABLE_TABLE_SIZE]
#define v_motor   variable_table[11]
#define VARIABLE_TABLE_SIZE   16
#define VH   PB3
#define VL   PB2
#define WH   PB5
#define WL   PB4

Functions

void intADC (void)
 Initializes ADC.
void intInterrupts (void)
 Enable Interrupts.
void intLEDPin (void)
 Initializes pin LED function.
void intPWM (void)
 Initializes Timer 1 as PWM output.
void intTACH (void)
 Initializes pin for Tachometer function.
void intTestPin (void)
 Initializes pin for Code testing function.
void intTimer0 (void)
 Initializes Timer 0 in Normal 16-bit mode.
 ISR (ADC_vect)
 ADC interrupt.
 ISR (TIMER1_OVF_vect)
 Timer 1 Overflow Interrupt.
 ISR (TIMER0_COMPA_vect)
 Timer 0 Output Compare A Interrupt.
int main (void)
 Main.
void read_eeprom (void)
 Reads EEPROM values.
void test_oscillator (void)
 Tests accuracy of Oscillator.
void write_eeprom (void)
 Writes EEPROM values.

Variables

uint8_t adc_mux_table_forward [6]
uint8_t adc_sample
uint8_t adc_sample_state = 0
uint8_t bemf_ready = 0
uint8_t bemf_sampled
uint8_t bit_count_low
uint8_t bit_position
uint8_t bit_test = 0
uint16_t bit_timeout
uint16_t byte_timeout
uint8_t comm_data
uint8_t comm_inter_state
uint16_t comm_period
uint16_t comm_period_temp
uint8_t commutation_step = 0
uint8_t commutation_step_sampled = 0
uint8_t control_state = 1
uint8_t count_dir
uint8_t data_in
uint8_t data_toggle
uint16_t delta
uint8_t eeprom_number
uint8_t get_bemf
uint8_t input_state = 1
uint16_t intercept
uint16_t led_blink_count = 0
uint8_t lower_comm_table_forward [6]
uint8_t motor_kiv
uint8_t motor_kpv
uint8_t motor_max_speed
uint8_t motor_min_speed
uint8_t motor_norm_speed
uint8_t motor_off
uint8_t neutral = 0
uint16_t neutral_averaging
uint16_t nr0 = 0
uint16_t nr0_temp = 0
uint8_t output_state = 1
uint8_t pin_test
uint16_t pwm_cmd
uint16_t pwm_cmd_filter
uint16_t pwm_cmd_filtered
uint16_t pwm_cmd_next
uint8_t pwm_cmd_updated
uint8_t pwm_counter = 0
uint16_t pwm_value
uint16_t r0 = 0
uint16_t r0_temp = 0
uint8_t s_loop_count = 0
uint16_t s_nr0 = 0
uint16_t s_r0 = 0
uint16_t s_y0 = 0
uint16_t s_y0_max
uint16_t s_y0_min
uint16_t s_y1 = 0
uint16_t slope
uint16_t speed_cmd_calc
uint8_t table_counter = 0
uint16_t timer_capture
uint16_t timer_capture_last
uint8_t upper_comm_table_forward [6]
uint8_t valid_byte
uint8_t variable_table [VARIABLE_TABLE_SIZE+EEPROM_TABLE_SIZE]
uint16_t y0 = 0
uint16_t y0_max
uint16_t y0_min
uint16_t y1 = 0
uint8_t zc_table_forward [6]

Detailed Description

 BLDC Sensorless Control using the ATtiny461A for Fan control.
Application note:
AVR625: Configurable Three Phase BLDC Fan
Documentation
For comprehensive code documentation, supported compilers, compiler settings and supported devices see readme.html
Author:
Atmel Corporation: http://www.atmel.com
Support email: avr@a.nosp@m.tmel.nosp@m..com
Name:
main.c
Revision:
2.0
Date:
2012-12-05 (Wed, 5 Dec 2012)


Definition in file main.c.


Define Documentation

#define ADC_MUX_I   0x22

Definition at line 122 of file main.c.

Referenced by intADC(), and ISR().

#define ADC_MUX_U   0x25

Definition at line 124 of file main.c.

#define ADC_MUX_V   0x26

Definition at line 125 of file main.c.

#define ADC_MUX_W   0x24

Definition at line 123 of file main.c.

#define ADC_PRESCALER   4

Definition at line 120 of file main.c.

Referenced by intADC().

#define bemf   variable_table[8]

Definition at line 313 of file main.c.

Referenced by ISR().

#define bemf_error   variable_table[9]

Definition at line 314 of file main.c.

Referenced by main().

#define CMD_PIN   PA4

Definition at line 97 of file main.c.

#define CMD_PIN_0   (1<<CMD_PIN)

Definition at line 99 of file main.c.

Referenced by test_oscillator().

#define CMD_PIN_1   0

Definition at line 100 of file main.c.

Referenced by ISR(), and test_oscillator().

#define CMD_PIN_TEST   (PINA & (1<<CMD_PIN))

Definition at line 98 of file main.c.

Referenced by ISR(), and test_oscillator().

#define command   variable_table[0]

Definition at line 301 of file main.c.

Referenced by main().

Definition at line 356 of file main.c.

Referenced by main().

Definition at line 358 of file main.c.

Referenced by main().

Definition at line 360 of file main.c.

Referenced by main().

Definition at line 362 of file main.c.

Referenced by main().

#define counter   variable_table[15]

Definition at line 324 of file main.c.

Referenced by main().

#define current   variable_table[5]

Definition at line 308 of file main.c.

Referenced by ISR(), and main().

#define current_limit   variable_table[4]

Definition at line 307 of file main.c.

Referenced by main().

Definition at line 351 of file main.c.

Referenced by main().

Definition at line 352 of file main.c.

Referenced by main().

Definition at line 350 of file main.c.

Referenced by main().

#define data_rxd   variable_table[14]

Definition at line 322 of file main.c.

Referenced by ISR().

Definition at line 329 of file main.c.

Referenced by main().

#define EDGE_FALLING   1

Definition at line 72 of file main.c.

#define EDGE_RISING   0

Definition at line 73 of file main.c.

#define EEPROM_TABLE_SIZE   32

Definition at line 131 of file main.c.

Referenced by ISR(), main(), read_eeprom(), and write_eeprom().

Definition at line 327 of file main.c.

Referenced by main().

#define HALF_LIMIT   0x7FFFu

Definition at line 93 of file main.c.

Referenced by main().

#define HEADER_SIZE   64

Definition at line 134 of file main.c.

Referenced by main().

Definition at line 331 of file main.c.

Referenced by main().

Definition at line 337 of file main.c.

Referenced by main().

Definition at line 336 of file main.c.

Referenced by main().

#define LED_PIN   PB6

Definition at line 114 of file main.c.

Referenced by intLEDPin().

#define LED_PIN_0   PORTB &= ~(1<<LED_PIN)

Definition at line 115 of file main.c.

#define LED_PIN_1   PORTB |= (1<<LED_PIN)

Definition at line 116 of file main.c.

#define LED_PIN_TOGGLE   PORTB ^= (1<<LED_PIN)

Definition at line 117 of file main.c.

Referenced by main().

#define LOOP_SCALING   3u

Definition at line 94 of file main.c.

Referenced by main().

#define LOWER_DRIVE_STEP1_CW   (1 << WL)

Definition at line 85 of file main.c.

#define LOWER_DRIVE_STEP2_CW   (1 << WL)

Definition at line 86 of file main.c.

#define LOWER_DRIVE_STEP3_CW   (1 << VL)

Definition at line 87 of file main.c.

#define LOWER_DRIVE_STEP4_CW   (1 << VL)

Definition at line 88 of file main.c.

#define LOWER_DRIVE_STEP5_CW   (1 << UL)

Definition at line 89 of file main.c.

#define LOWER_DRIVE_STEP6_CW   (1 << UL)

Definition at line 90 of file main.c.

Definition at line 330 of file main.c.

Referenced by main().

#define osc_cal   variable_table[12]

Definition at line 319 of file main.c.

Referenced by main().

Definition at line 328 of file main.c.

Referenced by main().

#define osc_error   variable_table[13]

Definition at line 320 of file main.c.

Referenced by test_oscillator().

Definition at line 338 of file main.c.

Referenced by main().

#define pwm   variable_table[7]

Definition at line 311 of file main.c.

Referenced by ISR(), and main().

#define pwm_limit   variable_table[6]

Definition at line 310 of file main.c.

Referenced by main().

Definition at line 340 of file main.c.

Referenced by main().

Definition at line 339 of file main.c.

Referenced by main().

Definition at line 335 of file main.c.

Referenced by main().

Definition at line 344 of file main.c.

Referenced by main().

Definition at line 343 of file main.c.

Referenced by main().

Definition at line 341 of file main.c.

Referenced by main().

Definition at line 342 of file main.c.

Referenced by main().

#define speed   variable_table[2]

Definition at line 304 of file main.c.

Referenced by main().

#define speed_cmd   variable_table[1]

Definition at line 303 of file main.c.

Referenced by main().

Definition at line 357 of file main.c.

Referenced by main().

Definition at line 359 of file main.c.

Referenced by main().

Definition at line 361 of file main.c.

Referenced by main().

Definition at line 363 of file main.c.

Referenced by main().

Definition at line 347 of file main.c.

Referenced by main().

Definition at line 346 of file main.c.

Referenced by main().

Definition at line 334 of file main.c.

Referenced by main().

Definition at line 333 of file main.c.

Referenced by main().

#define speed_error   variable_table[3]

Definition at line 305 of file main.c.

Referenced by main().

Definition at line 348 of file main.c.

Referenced by main().

#define TACH_PIN   PA0

Definition at line 104 of file main.c.

Referenced by intTACH().

#define TACH_PIN_0   PORTA |= (1<<TACH_PIN)

Definition at line 105 of file main.c.

Referenced by ISR().

#define TACH_PIN_1   PORTA &= ~(1<<TACH_PIN)

Definition at line 106 of file main.c.

Referenced by ISR().

#define TEST_PIN   PA3

Definition at line 109 of file main.c.

Referenced by intTestPin().

#define TEST_PIN_0   PORTA &= ~(1<<TEST_PIN)

Definition at line 110 of file main.c.

Referenced by ISR().

#define TEST_PIN_1   PORTA |= (1<<TEST_PIN)

Definition at line 111 of file main.c.

Referenced by ISR(), and test_oscillator().

#define UH   PB1

Definition at line 66 of file main.c.

Referenced by intPWM().

#define UL   PB0

Definition at line 65 of file main.c.

Referenced by intPWM().

#define UPPER_DRIVE_MASK   ((1 << UH) | (1 << VH) | (1 << WH))

Definition at line 75 of file main.c.

Referenced by ISR().

#define UPPER_DRIVE_STEP1_CW   (1 << VH)

Definition at line 77 of file main.c.

#define UPPER_DRIVE_STEP2_CW   (1 << UH)

Definition at line 78 of file main.c.

#define UPPER_DRIVE_STEP3_CW   (1 << UH)

Definition at line 79 of file main.c.

#define UPPER_DRIVE_STEP4_CW   (1 << WH)

Definition at line 80 of file main.c.

#define UPPER_DRIVE_STEP5_CW   (1 << WH)

Definition at line 81 of file main.c.

#define UPPER_DRIVE_STEP6_CW   (1 << VH)

Definition at line 82 of file main.c.

#define v_bus   variable_table[10]

Definition at line 316 of file main.c.

Referenced by ISR(), and main().

Definition at line 354 of file main.c.

Referenced by main().

#define v_motor   variable_table[11]

Definition at line 317 of file main.c.

Referenced by main().

#define VARIABLE_TABLE_SIZE   16

Definition at line 128 of file main.c.

Referenced by ISR(), main(), read_eeprom(), and write_eeprom().

#define VH   PB3

Definition at line 68 of file main.c.

Referenced by intPWM().

#define VL   PB2

Definition at line 67 of file main.c.

Referenced by intPWM().

#define WH   PB5

Definition at line 70 of file main.c.

Referenced by intPWM().

#define WL   PB4

Definition at line 69 of file main.c.

Referenced by intPWM().


Function Documentation

void intADC ( void  )

Initializes ADC.

ADC is initialized in single ended mode, Left Aligned for 8 bit values Using VCC as the reference. The conversion is triggered by the timer 1 overflow

Returns:
void

Definition at line 501 of file main.c.

References ADC_MUX_I, and ADC_PRESCALER.

Referenced by main().

{
        //PA1(ADC1)-DIR,PA5(ADC4)-THR,PA6(ADC5)-IB,PA7(ADC6)-IA,
        //PB6(ADC9)-V+,PB7(ADC10)-TEMP

        //ADMUX – ADC Multiplexer Selection Register
        //Bits 7:6 – REFS1:REFS0: Voltage Reference Selection Bits 00= Vcc
        //Bit 5 – ADLAR: ADC Left Adjust Result
        //Bits 4:0 – MUX4:0: Analog Channel and Gain Selection Bits
        ADMUX = ADC_MUX_I;

        //ADCSRA – ADC Control and Status Register A
        //Bit 7 – ADEN: ADC Enable
        //Bit 6 – ADSC: ADC Start Conversion
        //Bit 5 – ADATE: ADC Auto Trigger Enable
        //Bits 2:0 – ADPS2:0: ADC Prescaler Select Bits
        ADCSRA = ((1<<ADEN) | (1<<ADATE) | ADC_PRESCALER);
        
        //ADCL an ADCH – The ADC Data Register
        //read just ADCH for 8 bit values
                
        //ADCSRB – ADC Control and Status Register B
        //Timer/Counter1 Overflow - ADTS2 = 1, ADTS1 = 1, ADTS0 = 0
        ADCSRB = ((1<<ADTS2) | (1<<ADTS1));
        
        //DIDR0 – Digital Input Disable Register 0
        //Bits 7:4,2:0 – ADC6D:ADC0D: ADC6:0 Digital Input Disable
        //Bit 3 – AREFD: AREF Digital Input Disable
        DIDR0 |= ((1<<ADC2D)|(1<<ADC4D)|(1<<ADC5D)|(1<<ADC6D));
        
// ADATE in ADCSRA -  Auto Triggering is enabled by setting
// the ADC Auto Trigger Enable bit

// ADTS in ADCSRB - The trigger source is selected by setting
// the ADC Trigger Select bits
}
void intInterrupts ( void  )

Enable Interrupts.

Enables Timer0 Compare A, Timer1 overflow, and ADC end of conversion interrupts

Returns:
void

Definition at line 676 of file main.c.

Referenced by main().

{
        cli();
        //TIMSK – Timer/Counter1 Interrupt Mask Register
        //Bit 4 – OCIE0A: Timer/Counter0 Output Compare Match A Interrupt Enable
        TIMSK |= (1<<OCIE0A);
        //Bit 2 – TOIE1: Timer/Counter1 Overflow Interrupt Enable
        TIMSK |= (1<<TOIE1);
        //Bit 3 – ADIE: ADC Interrupt Enable
        ADCSRA |= (1<<ADIE);   //Bit 3 – ADIE: ADC Interrupt Enable
        sei();
}
void intLEDPin ( void  )

Initializes pin LED function.

Test pin is used on a spare pin to give a visual indicator that the code is running. The LED blinks at a rate that the proportional to the speed of the motor

Returns:
void

Definition at line 420 of file main.c.

References LED_PIN.

Referenced by main().

{
        PORTB &= ~(1<<LED_PIN);
        DDRB |= (1<<LED_PIN);
}
void intPWM ( void  )

Initializes Timer 1 as PWM output.

PWM is PWM6 / Dual-slope mode. The ADC conversion is triggered on a PWM reload. PWM is running at 19200Hz. PWM Overflow interrupt is used for UART Communications

Returns:
void

Definition at line 466 of file main.c.

References UH, UL, VH, VL, WH, and WL.

Referenced by main().

{
        //Clear on up-counting.
        TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << PWM1A);

        //Set WGM to PWM6, dual slope mode.
        TCCR1D = (1 << WGM11) | (1 << WGM10);

        // 16MHz/2/19200 = 417 counts, 0 to 416 (pwm + pwm>>1 + pwm>>3 + + pwm>>6)
        // (255+127+31+3)
        TC1H = 1;               //
        OCR1C = 0xA0;   //416 TOPVALUE (pwm + pwm>>1 + pwm>>3 + + pwm>>6)
        // (255+127+31+3)
        
        TCCR1B = (1 << CS10); //Prescaler 16MHz clock /1 = 16MHz
        
        //Set PWM pins as output.
        // (PWM output is still controlled through TCCR1E register.)
        DDRB = (1 << UL)|(1 << UH)|(1 << VL)|(1 << VH)|(1 << WL)|(1 << WH);
}
void intTACH ( void  )

Initializes pin for Tachometer function.

This function sends a command byte to the connected peripheral and waits for a returned status code.

Returns:
void

Definition at line 378 of file main.c.

References TACH_PIN.

Referenced by main().

{
        PORTA &= ~(1<<TACH_PIN);   // set PA0 low
        DDRA |= (1<<TACH_PIN);     // make PA0 an output 
}
void intTestPin ( void  )

Initializes pin for Code testing function.

Test pin is used on a spare pin to look at code timing using an oscilloscope. This is only for Debugging and benchmarking code TEST_PIN_1; and TEST_PIN_0; are inserted in code to set the pin high and low.

Returns:
void

Definition at line 400 of file main.c.

References TEST_PIN.

Referenced by main().

{
        PORTA &= ~(1<<TEST_PIN);
        DDRA |= (1<<TEST_PIN);
}
void intTimer0 ( void  )

Initializes Timer 0 in Normal 16-bit mode.

Timer 0 is used as the frequency generator for the Back EMF sensing Phase Locked Loop (PLL) by load the end count. An interrupt is generated on an Output Compare A Match and a new values is added on to the current value to create an interrupt that is variable frequency for the PLL. The interrupt alternates between triggering a back EMF sample or an update of commutation. The timer uses the 16MHz system clock with a /8 prescaler (2Mhz clock) The frequency of the timer interrupt is proportional to speed.

Returns:
void

Definition at line 445 of file main.c.

Referenced by main().

{
        // Set up Timer/counter0 
        TCCR0A = (1<<TCW0);  // Normal, 16-bit mode
        TCCR0B = (1<<CS01);  // Clk/8 Prescaler for 2MHz timer clock
}
ISR ( ADC_vect  )

ADC interrupt.

Interrupts on end of conversion. Used to store ADC sample in a variable. The sample alternates between current and Back EMF The back EMF samples are averaged to calculated the neutral point of the motor which is 1/2 the DC bus voltage.

Returns:
void

Definition at line 704 of file main.c.

References ADC_MUX_I, adc_mux_table_forward, adc_sample_state, bemf, bemf_ready, bemf_sampled, commutation_step, commutation_step_sampled, current, get_bemf, neutral, neutral_averaging, nr0_temp, pwm, r0_temp, TEST_PIN_0, TEST_PIN_1, v_bus, and zc_table_forward.

{
        TEST_PIN_1;
        if(adc_sample_state == 0 )
        {
                current = ADCH;
                ADMUX = adc_mux_table_forward[commutation_step];
                commutation_step_sampled = commutation_step;
                adc_sample_state = 1;
                
        }
        else
        {
                bemf_sampled = ADCH;
        
                if (get_bemf)
                {
                        
                        if (commutation_step_sampled == commutation_step)
                        {
                                bemf = bemf_sampled;
                                neutral_averaging = (neutral_averaging - neutral) + bemf; 
                                v_bus = neutral_averaging>>5;
                                neutral = v_bus>>1;
                                if (pwm < 20)
                                {
                                        // Below 20 counts sample window is too small
                                        v_bus = neutral;
                                }

                                bemf_ready = 1;
                                // Increasing Back EMF
                                if (zc_table_forward[commutation_step_sampled] == 0)
                                {
                                        if (bemf <= neutral)  // Too Fast
                                        {
                                                r0_temp = 0;
                                                nr0_temp = neutral - bemf;
                                        }
                                        else   // Too Slow
                                        {
                                                r0_temp = bemf - neutral;
                                                nr0_temp = 0;
                                        }
                                }
                                else
                                {
                                        if (bemf <= neutral)  // Too Slow
                                        {
                                                r0_temp = neutral - bemf;
                                                nr0_temp = 0;
                                        }
                                        else  // Too Fast
                                        {
                                                r0_temp = 0;
                                                nr0_temp = bemf - neutral;
                                        }
                                }
                        }
                        get_bemf = 0;
                }
                
                ADMUX = ADC_MUX_I;
                adc_sample_state = 0;
        }       
        
        TEST_PIN_0;
}
ISR ( TIMER1_OVF_vect  )

Timer 1 Overflow Interrupt.

Interrupt at the beginning of the PWM period. Used as time base for UART communication (Transmit and Receive) also to read in the PWM speed command Also handles counting PWM periods for main control loop timing and includes a UART timeout function so the software UART does not get hung up on interrupted data or if powered up in the middle of a UART byte.

Returns:
void

Definition at line 790 of file main.c.

References bit_count_low, bit_position, bit_timeout, byte_timeout, CMD_PIN_1, CMD_PIN_TEST, comm_data, data_in, data_rxd, eeprom_number, EEPROM_TABLE_SIZE, input_state, motor_off, output_state, pwm_cmd, pwm_cmd_next, pwm_cmd_updated, pwm_counter, TACH_PIN_0, TACH_PIN_1, TEST_PIN_0, TEST_PIN_1, valid_byte, variable_table, and VARIABLE_TABLE_SIZE.

{
        TEST_PIN_1;
        if (CMD_PIN_TEST == CMD_PIN_1)
        {
                pwm_cmd_next++;
                if (bit_position > 0)
                {
                        byte_timeout=0;
                        bit_timeout++;
                        if (bit_timeout > 1920) //100ms
                        {
                                bit_position = 0;
                        }
                }
                else
                {
                        bit_timeout = 0;
                }
                
                byte_timeout++;
                if((bit_count_low > 6)&&(bit_count_low < 10)) // 7, 8, or 9 PWM periods
                {
                        data_in = 0;
                        bit_position++;
                        bit_timeout = 0;
                }
                if((bit_count_low > 2)&&(bit_count_low < 6)) // 3, 4, or 5 PWM periods
                {
                        data_in = 1;
                        bit_position++;
                        bit_timeout = 0;
                }
                bit_count_low = 0;
        }
        else
        {
                bit_count_low++;
                if (bit_count_low > 9)
                {
                        bit_count_low = 10;
                        bit_position = 0;
                }
        }       
        if (pwm_counter == 0)
        {
                pwm_cmd = pwm_cmd_next;
                pwm_cmd_next = 0;
                pwm_cmd_updated = 1;
        }
        pwm_counter++;


        if (input_state == 1)
        {
                //Serial Data in (sort of) looking for 4 PWMs low = 1 and
                // 8 PWMs low = 0 only when UART receive enabled

                if (bit_position == 1)
                {
                        data_rxd = 0;  //valid start bit
                }
                if ((bit_position > 0)&&(bit_position < 9))
                {
                        data_rxd |= data_in<<(bit_position-1);
                }       
                if (bit_position == 8)
                {
                        valid_byte++;
                        bit_position = 0;  //start over
                }

                if ( byte_timeout >= 19200)  //29200/19200Hz = 1sec
                {
                        valid_byte=0;
                        byte_timeout=0;
                }

                if (valid_byte == 3)
                {
                        if (eeprom_number < EEPROM_TABLE_SIZE)
                        {
                                variable_table[eeprom_number + VARIABLE_TABLE_SIZE] = data_rxd;
                        }
                
                        valid_byte=0;
                        if ((eeprom_number == 254)&(data_rxd == 254))
                        {
                                motor_off = 5;//Motor off command and variables ready for write
                        }
                        if ((eeprom_number == 255)&(data_rxd == 255))
                        {
                                motor_off = 9; // Motor off command and calibrate oscillator
                        }                               
                }
                
                if (valid_byte == 1)
                {
                        eeprom_number = data_rxd;
                        valid_byte++;
                }
        }       
        else
        {
                valid_byte=0;
                byte_timeout=0;
        }
        
        // Software UART Transmit here
        if (output_state == 1)
        {
                if ((pwm_counter & 0x0F) == 0)
                {
                        TACH_PIN_0;  //Start Bit
                }       
                else
                {
                        if ((pwm_counter & 0x0F) < 9)
                        {
                                if (comm_data & 0x01)   //LSB first
                                {
                                        TACH_PIN_1;             // TXD = 1
                                }
                                else
                                {
                                        TACH_PIN_0;         // TXD = 0 
                                }

                                comm_data = comm_data>>1;
                        }
                        else
                        {
                                TACH_PIN_1;
                        }
                }
        }
        TEST_PIN_0;
}
ISR ( TIMER0_COMPA_vect  )

Timer 0 Output Compare A Interrupt.

Interrupt on Output Compare Register A The compare value forms the frequency for the back EMF sensing PLL. The interrupt alternates between sampling the back EMF and updating commutation. Updating commutation forms the beginning of the commutation state. The back EMF sample is in the middle of the commutation state, this should be the zero crossing point of the back EMF. This means there are two interrupt per commutation state and six states per commutation cycle (electrical cycle). The tachometer output is also handled in this interrupt.

Returns:
void

Definition at line 950 of file main.c.

References comm_inter_state, comm_period, commutation_step, get_bemf, lower_comm_table_forward, output_state, TACH_PIN_0, TACH_PIN_1, TEST_PIN_0, TEST_PIN_1, timer_capture, timer_capture_last, upper_comm_table_forward, and UPPER_DRIVE_MASK.

{
        TEST_PIN_1;
        if (comm_inter_state == 1) // back EMF sampling
        {
                get_bemf = 1;
                comm_inter_state = 0; // Update Commutation on next interrupt
        }

        else  // update commutation state 
        {
                commutation_step++;
                if (commutation_step>=6)
                {
                        commutation_step=0;
                }
                // Update commutation state
                TCCR1E = lower_comm_table_forward[commutation_step];
                PORTB &=  ~(UPPER_DRIVE_MASK);
                PORTB |= upper_comm_table_forward[commutation_step];
                
                if (output_state == 0) //Only update on proper commutation state edge
                {
                        if (commutation_step == 0)
                        {
                                TACH_PIN_0;
                        }
                        if (commutation_step == 3)
                        {
                                TACH_PIN_1;
                        }
                } 
                comm_inter_state = 1; // Back EMF sample on next interrupt
        }

        // Update Timer Compare Value
        timer_capture = timer_capture_last + comm_period;
        OCR0B = (timer_capture >> 8); 
        OCR0A = timer_capture; 
        timer_capture_last = timer_capture;

        TEST_PIN_0;

}
int main ( void  )

Main.

Main handles calling all initialization then sits in an infinite loop. The infinite loop forms the main control loop that is updated every 16 PWM cycles or 833us. The control loop handles all low speed function that do not require interrupt timing, this includes: Next UART byte for transmission Averaging of PWM input (speed command) Updating the back EMF sensing PLL if needed Speed command mapping Update speed loop Current limiting by folding back PWM duty cycle PWM update and various thresholds and house keeping.

Returns:
void

Definition at line 1018 of file main.c.

References bemf_error, bemf_ready, bit_test, comm_data, comm_period, comm_period_temp, command, command_0, command_1, command_2, command_3, control_state, count_dir, counter, current, current_limit, current_limit_max, current_limit_slope, current_limit_startup, data_toggle, data_watch, delta, EEPROM_TABLE_SIZE, enable_voltage, HALF_LIMIT, HEADER_SIZE, input_cmd, input_state, intADC(), intercept, intInterrupts(), intLEDPin(), intPWM(), intTACH(), intTestPin(), intTimer0(), ki, kp, led_blink_count, LED_PIN_TOGGLE, LOOP_SCALING, mode, motor_off, nr0, nr0_temp, osc_cal, osc_cal_adj, output_state, pll_gravity, pwm, pwm_cmd, pwm_cmd_filter, pwm_cmd_filtered, pwm_cmd_updated, pwm_counter, pwm_limit, pwm_max, pwm_min, pwm_value, r0, r0_limit, r0_temp, read_eeprom(), s_ki, s_kp, s_loop_count, s_loop_rate, s_nr0, s_r0, s_r0_limit, s_y0, s_y0_max, s_y0_min, s_y1, slope, speed, speed_cmd, speed_cmd_0, speed_cmd_1, speed_cmd_2, speed_cmd_3, speed_cmd_calc, speed_cmd_max, speed_cmd_min, speed_count_max, speed_count_min, speed_error, speed_scale, table_counter, test_oscillator(), v_bus, v_bus_min, v_motor, variable_table, VARIABLE_TABLE_SIZE, write_eeprom(), y0, y0_max, y0_min, and y1.

{
        intPWM();               // Initialize timer1 as PWM6 mode center aligned
        intTimer0();            // Initialize timer0 for commutation timing
        intTACH();              // Initialize I/O pin as tachometer out
        intTestPin();           // Initialize I/O pin as test pin
        intLEDPin();            // Initialize I/O pin as LED indicator
        intADC();               // Initialize ADC
        read_eeprom();          // Read the EEPROM contents once on power up
        intInterrupts();        // Enable interrupts
        
        osc_cal = OSCCAL;       // Read the factory calibration once on power up

    while(1)
    {
                
                led_blink_count++;
                if (led_blink_count >= comm_period_temp)
                {
                        LED_PIN_TOGGLE;
                        led_blink_count = 0;
                }

                //Recalculated limits in case they have changed from
                // Fan Configuration Utility
                y0_min = ((speed_count_min<<LOOP_SCALING) + HALF_LIMIT);
                y0_max = ((speed_count_max<<LOOP_SCALING) + HALF_LIMIT);
                s_y0_min = ((pwm_min<<LOOP_SCALING) + HALF_LIMIT);
                s_y0_max = ((pwm_max<<LOOP_SCALING) + HALF_LIMIT);
                        
                // Compare DC input voltage (V_bus) with enable_voltage,
                // below threshold use defaults
                if (v_bus <= enable_voltage)
                {
                        input_state = 1;      //0 = pwm input, 1 = UART Data In
                        output_state = 1;     //0 = Tach output, 1 = UART Data Out
                        control_state = 1;    //0 = Speed Control, 1 = Open Loop PWM
                        OSCCAL = osc_cal;
                }
                else
                {
                        input_state = (mode & 0x01);       //0 = PWM input,
                        // 1 = UART Data In
                        output_state = (mode & 0x02)>>1;   //0 = Tach output,
                        // 1 = UART Data Out
                        control_state = (mode & 0x04)>>2;  //0 = Speed Control,
                        // 1 = Open Loop PWM
                        if (osc_cal_adj < 33)
                        {
                                OSCCAL = osc_cal + osc_cal_adj - 16;
                        }
                        else
                        {
                                OSCCAL = osc_cal;
                        }       
                }
                
                // Wait here for 16 PWM periods to pass -
                // Timing for control loop 19200Hz/16 = 1200Hz (833us)
                cli();
                bit_test = (pwm_counter & 0x0F);
                sei();
                while(bit_test != 0x0F)
                {
                        cli();
                        bit_test = (pwm_counter & 0x0F);
                        sei();
                }
                cli();
                bit_test = (pwm_counter & 0x0F);
                sei();
                while(bit_test > 0)
                {               
                        cli();
                        bit_test = (pwm_counter & 0x0F);
                        sei();
                }

                // Calculate Motor Voltage
                v_motor = (v_bus*pwm)>>8;

                // Write EEPROM function here. Non-reentrant so must disable interrupts 
                if (motor_off == 7)   // bit 0 = motor off command,
                // bit 1 = motor turned off, bit 2 = transfer variables back to EEPROM,
                // bit 3 = Cal Oscillator
                {
                                write_eeprom();
                }
                if (motor_off == 11)   // bit 0 = motor off command,
                // bit 1 = motor turned off,
                // bit 2 = transfer variables back to EEPROM bit 3 = Cal Oscillator 
                {
                                test_oscillator();
                }

                // Serial Data Selection
                if (data_toggle)
                {
                        if (table_counter < (VARIABLE_TABLE_SIZE + EEPROM_TABLE_SIZE))
                        {
                                comm_data = variable_table[table_counter];
                        }
                        else
                        {
                                if (table_counter == (VARIABLE_TABLE_SIZE + EEPROM_TABLE_SIZE))
                                {
                                        comm_data = 0;      // 0 at end of data
                                }
                                else
                                {
                                        comm_data = 255;    // The rest of the data is 255s
                                }
                                
                        }
                        table_counter++;
                        if (table_counter > (HEADER_SIZE + VARIABLE_TABLE_SIZE +
                                 EEPROM_TABLE_SIZE + 1))
                        {               
                                table_counter = 0;
                                comm_data = 0;    // 0 at beginning of data
                                
                        }
                        data_toggle = 0;
                }
                else
                {
                        
                        if (count_dir == 0)
                        {
                                counter++;
                                if (counter>254)
                                {
                                        count_dir = 1;
                                }
                        }
                        else
                        {
                                counter--;
                                if (counter<1)
                                {
                                        count_dir = 0;
                                }
                        }
                        
                        comm_data = variable_table[data_watch];
                        if (comm_data > 254)
                        {
                                comm_data = 254; // Clip data at 254
                        }
                        data_toggle = 1;
                }


                // PWM input (Speed command) averaging filter
                if (pwm_cmd_updated == 1)
                {
                        pwm_cmd_updated = 0;
                        pwm_cmd_filter = (pwm_cmd_filter - pwm_cmd_filtered) + pwm_cmd;
                        pwm_cmd_filtered = pwm_cmd_filter>>6;
                        if (pwm_cmd_filtered > 255)
                        {
                                pwm_cmd_filtered = 255;
                        }
                }


                // Check to see where command comes from either
                // Fan Configuration Utility of PWM input (Speed command)
                if (input_state == 1)
                {
                        command = input_cmd;
                }
                else
                {
                        command = pwm_cmd_filtered;
                }


                // Back EMF Sensing PLL Update
                if (bemf_ready == 1)
                {

                        cli();
                        bemf_ready = 0;
                        r0=r0_temp;
                        nr0=nr0_temp;
                        sei();
                
                        // Back EMF sensing PLL PI regulator
                        if(r0>r0_limit)
                        {
                                r0=r0_limit;
                        }
                        if(nr0>r0_limit)
                        {
                                nr0=r0_limit;
                        }               

                        nr0 += pll_gravity;
                        
                        bemf_error = 128 + r0 - nr0;
                        
                        y1 += ((r0*ki)>>8);    // ki
                        y1 -= ((nr0*ki)>>8);   // ki
                
                        if (y1 < y0_min)
                        {
                                y1 = y0_min; 
                        }
                        if (y1 > y0_max)
                        {
                                y1 = y0_min;      // Restart PLL
                        }
                        
                        y0 = y1 + ((r0*kp)>>8) - ((nr0*kp)>>8);   // kp
                        
                        if (y0 < y0_min)
                        {
                                y0 = y0_min; 
                        }
                        if (y0 > y0_max)
                        {
                                y0 = y0_min;    // Restart PLL
                        }                       
                        
                        if (speed_cmd < speed_cmd_min)
                        {
                                y1 = y0_min;    // Restart PLL
                        }
                
                        speed = (y0 - HALF_LIMIT) >> LOOP_SCALING;

                        comm_period_temp = (0xFFFF/speed)>>speed_scale;

                        cli();
                        comm_period = comm_period_temp;
                        sei();
                }
        

                // Speed Control Loop Update
                s_loop_count++;
                if (s_loop_count >= s_loop_rate)
                {
                        s_loop_count = 0;
                        // Speed command Mapping 
                        
                        if (command > command_3)
                        {
                                slope = 255 - speed_cmd_3;
                                delta = command - command_3;
                                intercept = speed_cmd_3;
                        }
                        else
                        {
                                if (command > command_2)
                                {
                                        slope = speed_cmd_3 - speed_cmd_2;
                                        delta = command - command_2;
                                        intercept = speed_cmd_2;        
                                }
                                else
                                {
                                        if (command > command_1)
                                        {
                                                slope = speed_cmd_2 - speed_cmd_1;
                                                delta = command - command_1;
                                                intercept = speed_cmd_1;
                                        }
                                        else
                                        {
                                                if (command > command_0)
                                                {
                                                        slope = speed_cmd_1 - speed_cmd_0;
                                                        delta = command - command_0;
                                                        intercept = speed_cmd_0;
                                                }
                                                else
                                                {
                                                        slope = 0;
                                                        delta = 0;
                                                        intercept = 0;
                                                }
                                        }
                                }
                        }
                        
                        speed_cmd_calc = ((slope*delta)/255) + intercept;

//                      speed_cmd = command; //Linear Mapping for testing purposes
                                
                        if (speed_cmd_calc > speed_cmd_max)
                        {
                                speed_cmd_calc = speed_cmd_max;
                        }
                        
                        if (speed_cmd_calc < speed_cmd_min)
                        {
                                speed_cmd_calc = speed_cmd_min;
                        }
                        
                        speed_cmd = speed_cmd_calc;
                        
                        // Speed Control PI regulator
                        if (speed > speed_cmd)
                        {
                                s_nr0 = speed - speed_cmd;
                                s_r0 = 0;
                        }
                        else
                        {
                                s_r0 = speed_cmd - speed;
                                s_nr0 = 0; 
                        }

                        if(s_nr0>s_r0_limit)
                        {
                                s_nr0=s_r0_limit;
                        }
                        if(s_r0>s_r0_limit)
                        {
                                s_r0=s_r0_limit;
                        }               


                        speed_error = 128 - s_r0 - s_nr0;

                        s_y1 += ((s_r0*s_ki)>>6);   //s_ki
                        s_y1 -= ((s_nr0*s_ki)>>6);  //s_ki
                        
                        if (s_y1 < s_y0_min)
                        {
                                s_y1 = s_y0_min; 
                        }
                        if (s_y1 > s_y0_max)
                        {
                                s_y1 = s_y0_max;
                        }
                        
                        s_y0 = s_y1 + ((s_r0*s_kp)>>6) - ((s_nr0*s_kp)>>6); //s_kp 
                        
                        if (s_y0 < s_y0_min)
                        {
                                s_y0 = s_y0_min; 
                        }
                        if (s_y0 > s_y0_max)
                        {
                                s_y0 = s_y0_max;
                        }                       
        
                        pwm = (s_y0 - HALF_LIMIT) >> LOOP_SCALING;
                }

                // Open Loop PWM or Speed Control
                if (control_state == 1)  // Direct PWM command for testing purposes
                {
                        
                        if (command>pwm_max)
                        {
                                pwm = pwm_max;
                        }
                        else
                        {
                                pwm = command;
                                if (pwm < pwm_min)
                                {
                                        pwm = pwm_min;
                                }
                        }
                }                       

                // Current limiting
                if (speed < speed_cmd_min )
                {       
                        // Lower Current limit gives better startup performance
                        current_limit = current_limit_startup;
                }
                else   //Higher current limit for high speed operation
                {
                        current_limit = current_limit_startup + 
                                ((((speed - speed_cmd_min)*current_limit_slope)>>8));
                        if (current_limit > current_limit_max)
                        {
                                // upper current limit for high power operation
                                current_limit = current_limit_max;
                        }
                }
                
                // Folds back PWM when exceeding current limit
                if (current > current_limit)
                {
//                      TEST_PIN_1;
                        if (pwm_limit > 1)
                        {
                                pwm_limit--;
                        }
                }
                else
                {
                        if (pwm_limit < pwm)
                        {
                                pwm_limit++;
                        }
                }       

                if (pwm > pwm_limit)
                {
                        pwm = pwm_limit;
                }

                // Minimum DC Bus Voltage before enabling
                // back EMF sensing and speed control
                if (v_bus < v_bus_min)
                {
                        pwm = pwm_min;
                        s_y1 = s_y0_min;   // Reset Integrator
                        s_y0 = 0;          // PWM off
                        y1 = y0_min;       // Restart PLL
                }
                
                // Motor Off function for updating EEPROM 
                if (motor_off == 0)
                {
                        // 16MHz/2/19200 = 417 counts, 0 to 416 
                        // (pwm + pwm>>1 + pwm>>3 + + pwm>>6) (255+127+31+3)
                        pwm_value = pwm + (pwm>>1) + (pwm>>3) + (pwm>>6);
                        cli();
                        TC1H = (pwm_value >> 8); 
                        OCR1A = pwm_value;
                        sei();
                }
                else
                {
                        cli();
                        TC1H = 0; 
                        OCR1A = 0;
                        motor_off |= 2;  // Motor PWM at zero
                        sei();
                        //pwm = pwm_min;
                        s_y1 = s_y0_min;   // Reset Integrator
                        s_y0 = 0;          // PWM off
                        y1 = y0_min;       // Restart PLL
                }

    }
}
void read_eeprom ( void  )

Reads EEPROM values.

EEPROM values are used for configuration of motor parameters These values are configured and updated from the PC based Fan Configuration Utility

Returns:
void

Definition at line 553 of file main.c.

References EEPROM_TABLE_SIZE, table_counter, variable_table, and VARIABLE_TABLE_SIZE.

Referenced by main().

void test_oscillator ( void  )

Tests accuracy of Oscillator.

Compares to USB to UART bridge oscillator to ATtiny internal oscillator

Returns:
void

Definition at line 608 of file main.c.

References CMD_PIN_0, CMD_PIN_1, CMD_PIN_TEST, comm_period, motor_off, osc_error, pin_test, and TEST_PIN_1.

Referenced by main().

{
        cli();
        //PC sends stream of 0 bytes at 19200 baud, for a 468.75us period
        
        OCR0B = 0xFF; 
        OCR0A = 0xFF; 
        
        //Capture timer period 
        pin_test = CMD_PIN_TEST;
        while (pin_test == CMD_PIN_1)   //wait while pin is high
        {
                pin_test = CMD_PIN_TEST;
        }
        
//      TEST_PIN_0;     
        
        pin_test = CMD_PIN_TEST;
        while (pin_test == CMD_PIN_0)   //wait while pin is low
        {
                pin_test = CMD_PIN_TEST;
        }

        TEST_PIN_1;

        pin_test = CMD_PIN_TEST;
        while (pin_test == CMD_PIN_1)   //wait while pin is high
        {
                pin_test = CMD_PIN_TEST;
        }

        //Capture timer value
        TCNT0H = 0;
        TCNT0L = 0;

//      TEST_PIN_0;     

        pin_test = CMD_PIN_TEST;
        while (pin_test == CMD_PIN_0)   //wait while pin is low
        {
                pin_test = CMD_PIN_TEST;
        }
        //Capture timer value again
        comm_period = TCNT0L;
        comm_period += (TCNT0H<<8);

//      TEST_PIN_1;     
        //At 2us per count period and a period of 468.75us the count should be 234.
        osc_error = comm_period + 128 - 833;
        motor_off = 0;
        
//      TEST_PIN_0;
        
        sei();
}
void write_eeprom ( void  )

Writes EEPROM values.

EEPROM values are used for configuration of motor parameters These values are configured and updated from the PC based Fan Configuration Utility

Returns:
void

Definition at line 580 of file main.c.

References EEPROM_TABLE_SIZE, motor_off, table_counter, variable_table, and VARIABLE_TABLE_SIZE.

Referenced by main().

{
        cli();
        table_counter = 0;
        while (table_counter < EEPROM_TABLE_SIZE)
        {
                eeprom_write_byte ((uint8_t*)(table_counter),
                        variable_table[VARIABLE_TABLE_SIZE + table_counter]);
                table_counter++;
        }
        table_counter = 0;
//      update_limits();
        motor_off = 0;
        sei();
}

Variable Documentation

Initial value:

Definition at line 141 of file main.c.

Referenced by ISR().

uint8_t adc_sample

Definition at line 221 of file main.c.

uint8_t adc_sample_state = 0

Definition at line 251 of file main.c.

Referenced by ISR().

uint8_t bemf_ready = 0

Definition at line 253 of file main.c.

Referenced by ISR(), and main().

uint8_t bemf_sampled

Definition at line 220 of file main.c.

Referenced by ISR().

uint8_t bit_count_low

Definition at line 281 of file main.c.

Referenced by ISR().

uint8_t bit_position

Definition at line 282 of file main.c.

Referenced by ISR().

uint8_t bit_test = 0

Definition at line 196 of file main.c.

Referenced by main().

uint16_t bit_timeout

Definition at line 283 of file main.c.

Referenced by ISR().

uint16_t byte_timeout

Definition at line 284 of file main.c.

Referenced by ISR().

uint8_t comm_data

Definition at line 247 of file main.c.

Referenced by ISR(), and main().

Definition at line 217 of file main.c.

Referenced by ISR().

uint16_t comm_period

Definition at line 203 of file main.c.

Referenced by ISR(), main(), and test_oscillator().

uint16_t comm_period_temp

Definition at line 204 of file main.c.

Referenced by main().

uint8_t commutation_step = 0

Definition at line 202 of file main.c.

Referenced by ISR().

Definition at line 254 of file main.c.

Referenced by ISR().

uint8_t control_state = 1

Definition at line 264 of file main.c.

Referenced by main().

uint8_t count_dir

Definition at line 291 of file main.c.

Referenced by main().

uint8_t data_in

Definition at line 285 of file main.c.

Referenced by ISR().

uint8_t data_toggle

Definition at line 248 of file main.c.

Referenced by main().

uint16_t delta

Definition at line 237 of file main.c.

Referenced by main().

uint8_t eeprom_number

Definition at line 272 of file main.c.

Referenced by ISR().

uint8_t get_bemf

Definition at line 222 of file main.c.

Referenced by ISR().

uint8_t input_state = 1

Definition at line 262 of file main.c.

Referenced by ISR(), and main().

uint16_t intercept

Definition at line 238 of file main.c.

Referenced by main().

uint16_t led_blink_count = 0

Definition at line 267 of file main.c.

Referenced by main().

uint8_t motor_kiv

Definition at line 275 of file main.c.

uint8_t motor_kpv

Definition at line 274 of file main.c.

uint8_t motor_max_speed

Definition at line 276 of file main.c.

uint8_t motor_min_speed

Definition at line 278 of file main.c.

Definition at line 277 of file main.c.

uint8_t motor_off

Definition at line 287 of file main.c.

Referenced by ISR(), main(), test_oscillator(), and write_eeprom().

uint8_t neutral = 0

Definition at line 256 of file main.c.

Referenced by ISR().

Definition at line 255 of file main.c.

Referenced by ISR().

uint16_t nr0 = 0

Definition at line 228 of file main.c.

Referenced by main().

uint16_t nr0_temp = 0

Definition at line 230 of file main.c.

Referenced by ISR(), and main().

uint8_t output_state = 1

Definition at line 263 of file main.c.

Referenced by ISR(), and main().

uint8_t pin_test

Definition at line 289 of file main.c.

Referenced by test_oscillator().

uint16_t pwm_cmd

Definition at line 209 of file main.c.

Referenced by ISR(), and main().

uint16_t pwm_cmd_filter

Definition at line 212 of file main.c.

Referenced by main().

uint16_t pwm_cmd_filtered

Definition at line 213 of file main.c.

Referenced by main().

uint16_t pwm_cmd_next

Definition at line 210 of file main.c.

Referenced by ISR().

uint8_t pwm_cmd_updated

Definition at line 211 of file main.c.

Referenced by ISR(), and main().

uint8_t pwm_counter = 0

Definition at line 194 of file main.c.

Referenced by ISR(), and main().

uint16_t pwm_value

Definition at line 199 of file main.c.

Referenced by main().

uint16_t r0 = 0

Definition at line 227 of file main.c.

Referenced by main().

uint16_t r0_temp = 0

Definition at line 229 of file main.c.

Referenced by ISR(), and main().

uint8_t s_loop_count = 0

Definition at line 259 of file main.c.

Referenced by main().

uint16_t s_nr0 = 0

Definition at line 242 of file main.c.

Referenced by main().

uint16_t s_r0 = 0

Definition at line 241 of file main.c.

Referenced by main().

uint16_t s_y0 = 0

Definition at line 239 of file main.c.

Referenced by main().

uint16_t s_y0_max

Definition at line 244 of file main.c.

Referenced by main().

uint16_t s_y0_min

Definition at line 243 of file main.c.

Referenced by main().

uint16_t s_y1 = 0

Definition at line 240 of file main.c.

Referenced by main().

uint16_t slope

Definition at line 236 of file main.c.

Referenced by main().

uint16_t speed_cmd_calc

Definition at line 235 of file main.c.

Referenced by main().

uint8_t table_counter = 0

Definition at line 295 of file main.c.

Referenced by main(), read_eeprom(), and write_eeprom().

uint16_t timer_capture

Definition at line 205 of file main.c.

Referenced by ISR().

Definition at line 206 of file main.c.

Referenced by ISR().

uint8_t valid_byte

Definition at line 271 of file main.c.

Referenced by ISR().

Definition at line 298 of file main.c.

Referenced by ISR(), main(), read_eeprom(), and write_eeprom().

uint16_t y0 = 0

Definition at line 225 of file main.c.

Referenced by main().

uint16_t y0_max

Definition at line 232 of file main.c.

Referenced by main().

uint16_t y0_min

Definition at line 231 of file main.c.

Referenced by main().

uint16_t y1 = 0

Definition at line 226 of file main.c.

Referenced by main().

uint8_t zc_table_forward[6]
Initial value:

Definition at line 177 of file main.c.

Referenced by ISR().